"""
Redis Set 方法封装
"""

from redis.commands import list_or_args

from db_base.redis_db import (
    modify_name_prefix,
    name_add_prefix,
)
from db_base.redis_db.client import redis_client
from my_typing import *


class Set:
    """ 集合 """

    @staticmethod
    @modify_name_prefix
    def add(
        name: str,
        *values: bytes | float | int | str,
    ) -> int:
        """
        向集合 name 添加 values

        Args:
            name: 集合键的名称
            values: values

        Returns:
            添加成功的数量
        """

        return redis_client.sadd(name, *values)

    @staticmethod
    @modify_name_prefix
    def length(name: str) -> int:
        """
        获取集合 name 的元素数量

        Args:
            name: 集合键的名称

        Returns:
            元素数量
        """

        return redis_client.scard(name)

    @staticmethod
    def diff(
        keys: bytes | float | int | str | list[bytes | float | int | str],
        *args: bytes | float | int | str,
    ) -> Awaitable[list] | list:
        """
        获取集合 keys 中第一个 name 与其他 name 的差集（在第一个 name 对应的集合中，不在其他 name 对应的集合中）

        Args:
            keys: key

        Returns:
            key 的值
        """

        _names: ListStr = list(
            map(
                name_add_prefix,
                list_or_args(keys, args)
            )
        )

        return redis_client.sdiff(_names)

    @staticmethod
    def inter(
        keys: bytes | float | int | str | list[bytes | float | int | str],
        *args: bytes | float | int | str,
    ) -> Awaitable[list] | list:
        """
        获取集合 keys 中第一个 name 与其他 name 的交集（在第一个 name 对应的集合中，也在其他 name 对应的集合中）

        Args:
            keys: key

        Returns:
            key 的值
        """

        _names: ListStr = list(
            map(
                name_add_prefix,
                list_or_args(keys, args)
            )
        )

        return redis_client.sinter(_names)

    @staticmethod
    @modify_name_prefix
    def is_member(
        name: str,
        value: bytes | float | int | str,
    ) -> Literal[0, 1] | Awaitable[Literal[0, 1]]:
        """
        判断 value 是否为集合 name 的成员

        Args:
            name: 集合键的名称
            value: 值

        Returns:
            0 / 1
        """

        return redis_client.sismember(name, value)

    @staticmethod
    @modify_name_prefix
    def members(name: str) -> SetStr:
        """
        获取集合 name 的成员

        Args:
            name: 集合键的名称

        Returns:
            集合成员
        """

        return redis_client.smembers(name)
